package org.jeecg.modules.business.takestockplan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.print.entity.PrintConfig;
import org.jeecg.modules.basic.print.entity.WmsDocumentTypeStatus;
import org.jeecg.modules.basic.print.service.IPrintConfigService;
import org.jeecg.modules.basic.print.service.IWmsDocumentTypeStatusService;
import org.jeecg.modules.basic.unit.entity.BasicUnit;
import org.jeecg.modules.basic.unit.service.IBasicUnitService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaLocationService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseService;
import org.jeecg.modules.business.doc.business.entity.WmsInReceiptMaterial;
import org.jeecg.modules.business.doc.business.vo.WmsInReceiptPage;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceiptMaterial;
import org.jeecg.modules.business.doc.outbound.vo.WmsOutReceiptPage;
import org.jeecg.modules.business.takestockplan.entity.*;
import org.jeecg.modules.business.takestockplan.entity.VO.TakeStockPlanExecuteVO;
import org.jeecg.modules.business.takestockplan.entity.VO.TakeStockResultMaterialVO;
import org.jeecg.modules.business.takestockplan.entity.VO.TakeStockResultVO;
import org.jeecg.modules.business.takestockplan.mapper.TakeStockPlanDifferenceMaterialMapper;
import org.jeecg.modules.business.takestockplan.mapper.TakeStockPlanExecuteMapper;
import org.jeecg.modules.business.takestockplan.mapper.TakeStockPlanExecuteMaterialMapper;
import org.jeecg.modules.business.takestockplan.mapper.TakeStockResultMapper;
import org.jeecg.modules.business.takestockplan.service.ITakeStockPlanDifferenceService;
import org.jeecg.modules.business.takestockplan.service.ITakeStockPlanExecuteMaterialService;
import org.jeecg.modules.business.takestockplan.service.ITakeStockPlanService;
import org.jeecg.modules.business.takestockplan.service.ITakeStockResultService;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouse;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseAreaLocation;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 盘盈盘亏单
 * @Author: jeecg-boot
 * @Date: 2023-08-08
 * @Version: V1.0
 */
@Service
public class TakeStockResultServiceImpl extends ServiceImpl<TakeStockResultMapper, TakeStockResult> implements ITakeStockResultService {

    @Autowired
    private TakeStockResultMapper takeStockResultMapper;

    @Autowired
    private TakeStockPlanExecuteMapper takeStockPlanExecuteMapper;

    @Autowired
    private TakeStockPlanExecuteMaterialMapper takeStockPlanExecuteMaterialMapper;

    @Autowired
    private IWmsBasicWarehouseService wmsBasicWarehouseService;

    @Autowired
    private IWmsBasicWarehouseAreaService wmsBasicWarehouseAreaService;

    @Autowired
    private IWmsBasicWarehouseAreaLocationService wmsBasicWarehouseAreaLocationService;

    @Autowired
    private IBasicUnitService basicUnitService;

    @Autowired
    private ISysBaseAPI iSysBaseAPI;

    @Autowired
    private IPrintConfigService printConfigService;

    @Autowired
    private IWmsDocumentTypeStatusService documentTypeStatusService;

    @Autowired
    private ITakeStockPlanService takeStockPlanService;

    @Autowired
    private ITakeStockPlanExecuteMaterialService takeStockPlanExecuteMaterialService;

    @Autowired
    private IBasicMaterialService basicMaterialService;

    @Autowired
    private WorkFlowService workFlowService;

    @Autowired
    @Lazy
    private ITakeStockPlanDifferenceService takeStockPlanDifferenceService;
    @Autowired
    private TakeStockPlanDifferenceMaterialMapper takeStockPlanDifferenceMaterialMapper;

    /**
     * 分页
     *
     * @param page
     * @param takeStockResult
     * @return
     */
    @Override
    public Page<TakeStockResultVO> listByPage(Page<TakeStockResultVO> page, TakeStockResultVO takeStockResult) {
        return page.setRecords(takeStockResultMapper.listByPage(page, takeStockResult));
    }

    /**
     * 通过id删除
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteResult(String id) {
        // 删除盘盈和盘亏单
        TakeStockResult byId = this.getById(id);
        String executeId = byId.getTakeStockPlanDifferenceId();
        List<TakeStockResult> list = this.list(new LambdaQueryWrapper<TakeStockResult>()
                .eq(TakeStockResult::getTakeStockPlanDifferenceId, executeId));
        this.removeBatchByIds(list);
        // 变更盘点差异处理单相关信息
        takeStockPlanDifferenceService.update(new LambdaUpdateWrapper<TakeStockPlanDifference>()
                .eq(TakeStockPlanDifference::getId, executeId)
                .set(TakeStockPlanDifference::getInventoryGainId, null)
                .set(TakeStockPlanDifference::getInventoryLossId, null)
//                .set(TakeStockPlanDifference::getDocumentStatus, "2")
                .set(TakeStockPlanDifference::getGenerateFlag, "0"));
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @Override
    public TakeStockResultMaterialVO getResultById(String id) {
        TakeStockResultMaterialVO takeStockResult = takeStockResultMapper.getResultById(id);
        if (takeStockResult == null) {
            throw new JeecgBootException("未找到对应数据");
        }
        String wmsTakeStockPlanExecuteMaterialId = takeStockResult.getTakeStockPlanDifferenceMaterialId();
        List<TakeStockPlanDifferenceMaterial> list = takeStockPlanDifferenceMaterialMapper.selectBatchIds(Arrays.asList(wmsTakeStockPlanExecuteMaterialId.split(",")));
        for (TakeStockPlanDifferenceMaterial material : list) {
            WmsBasicWarehouse warehouse = wmsBasicWarehouseService.getById(material.getWmsBasicWarehouseId());
            material.setWmsBasicWarehouseName(Optional.ofNullable(warehouse).map(WmsBasicWarehouse::getName).orElse(""));
            WmsBasicWarehouseArea area = wmsBasicWarehouseAreaService.getById(material.getWmsBasicWarehouseAreaId());
            material.setWmsBasicWarehouseAreaName(Optional.ofNullable(area).map(WmsBasicWarehouseArea::getName).orElse(""));
            WmsBasicWarehouseAreaLocation location = wmsBasicWarehouseAreaLocationService.getById(material.getWmsBasicWarehouseAreaLocationId());
            material.setWmsBasicWarehouseAreaLocationName(Optional.ofNullable(location).map(WmsBasicWarehouseAreaLocation::getName).orElse(""));
            BasicUnit unit = basicUnitService.getById(material.getWmsBasicUnitId());
            material.setWmsBasicUnitName(Optional.ofNullable(unit).map(BasicUnit::getName).orElse(""));
            BasicUnit unitSub = basicUnitService.getById(material.getUnitSub());
            material.setUnitSubName(Optional.ofNullable(unitSub).map(BasicUnit::getName).orElse(""));
        }
        takeStockResult.setTakeStockPlanDifferenceMaterialList(list);
        return takeStockResult;
    }

    /**
     * 盘盈入库
     *
     * @param id
     */
    @Override
    public void addInReceipt(String id) {
        TakeStockResult byId = this.getById(id);
        TakeStockPlanDifference difference = takeStockPlanDifferenceService.getById(byId.getTakeStockPlanDifferenceId());
        TakeStockPlanExecute execute = takeStockPlanExecuteMapper.selectById(difference.getTakeStockPlanExecuteId());
        TakeStockPlan plan = takeStockPlanService.getById(execute.getWmsTakeStockPlanId());

        BaseFlowDto base = new BaseFlowDto();
        base.setBusinessType("document_type");
        List<DictModel> dictList = iSysBaseAPI.getDictItems("document_type");
        DictModel dict = dictList.stream().filter(a -> a.getText().contains("盘盈")).collect(Collectors.toList()).get(0);
        base.setDocumentType(dict.getValue());
        base.setInfoId("");
        PrintConfig config = printConfigService.getOne(new LambdaQueryWrapper<PrintConfig>()
                .eq(PrintConfig::getBusinessType, "document_type")
                .eq(PrintConfig::getDocumentType, dict.getValue())
                .last("limit 1"));
        WmsDocumentTypeStatus typeStatus = documentTypeStatusService.getOne(new LambdaQueryWrapper<WmsDocumentTypeStatus>()
                .eq(WmsDocumentTypeStatus::getPrintConfigId, config.getId())
                .like(WmsDocumentTypeStatus::getName, "提交")
                .orderByAsc(WmsDocumentTypeStatus::getSort)
                .last("limit 1"));
        base.setCode(typeStatus.getCode());
        WmsInReceiptPage page = new WmsInReceiptPage();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//        List<DictModel> dictModels = iSysBaseAPI.queryAllDepartBackDictModel();
//        String deptId = iSysBaseAPI.getDepartIdsByOrgCode(sysUser.getOrgCode());
//        DictModel model = dictModels.stream().filter(a -> deptId.equals(a.getValue())).collect(Collectors.toList()).get(0);
        page.setOrganization(sysUser.getOrgCode());
        page.setDocumentType(dict.getValue());
        page.setDocumentCode(FillRuleUtil.executeRule(FillRuleConstant.IN_RECEIPT, new JSONObject()).toString());
        page.setOwnerType(plan.getOwnerType());
        page.setOwner(plan.getOwner());
        page.setWarehousingDate(new Date());
        page.setSysOrgCode(sysUser.getOrgCode());
        page.setWmsBasicWarehouseGroupId(plan.getWmsBasicWarehouseGroupId());
        page.setWmsBasicSupplierId(plan.getCustomerId());
        page.setDocumentStatus("200");
        page.setIsBackCommit(0);
        page.setJumpSecondCheck(true);
        List<TakeStockPlanDifferenceMaterial> materialList = takeStockPlanDifferenceMaterialMapper.selectBatchIds(Arrays.asList(byId.getTakeStockPlanDifferenceMaterialId().split(",")));
        List<WmsInReceiptMaterial> materials = new ArrayList<>();
        for (int i = 0; i < materialList.size(); i++) {
            TakeStockPlanDifferenceMaterial material = materialList.get(i);
            WmsInReceiptMaterial receiptMaterial = BeanUtil.toBean(material, WmsInReceiptMaterial.class);
            receiptMaterial.setWmsBasicMaterialId(material.getMaterialId());
            receiptMaterial.setWarehouseQuantity(new BigDecimal(material.getInventoryProfit()));
            receiptMaterial.setReceivableQuantity(new BigDecimal(material.getInventoryProfit()));
            receiptMaterial.setUpstreamDocuments("盘盈单");
            receiptMaterial.setUpstreamNumber(byId.getCode());
            if (StringUtils.isNotBlank(material.getInventoryProfitAssistant())) {
                receiptMaterial.setAssistQuantity(new BigDecimal(material.getInventoryProfitAssistant()));
            }
            receiptMaterial.setCreateBy(null);
            receiptMaterial.setCreateTime(null);
            receiptMaterial.setUpdateBy(null);
            receiptMaterial.setUpdateTime(null);
            receiptMaterial.setId(null);
            receiptMaterial.setUpstreamLineNumber(String.valueOf(i + 1));
            receiptMaterial.setProductNumber(material.getProductCode());
            materials.add(receiptMaterial);
        }
        page.setWmsInReceiptMaterialList(materials);
        base.setData(page);
        workFlowService.commit(base);

        byId.setWmsInReceiptId(base.getInfoId());
        byId.setGenerateFlag("1");
        this.updateById(byId);
    }

    /**
     * 盘亏出库
     *
     * @param id
     */
    @Override
    public void addOutReceipt(String id) {
        TakeStockResult byId = this.getById(id);
        TakeStockPlanDifference difference = takeStockPlanDifferenceService.getById(byId.getTakeStockPlanDifferenceId());
        TakeStockPlanExecute execute = takeStockPlanExecuteMapper.selectById(difference.getTakeStockPlanExecuteId());
        TakeStockPlan plan = takeStockPlanService.getById(execute.getWmsTakeStockPlanId());

        BaseFlowDto base = new BaseFlowDto();
        base.setBusinessType("outbound_type");
        List<DictModel> dictList = iSysBaseAPI.getDictItems("outbound_type");
        DictModel dict = dictList.stream().filter(a -> a.getText().contains("盘亏")).collect(Collectors.toList()).get(0);
        base.setDocumentType(dict.getValue());
        base.setInfoId("");
        PrintConfig config = printConfigService.getOne(new LambdaQueryWrapper<PrintConfig>()
                .eq(PrintConfig::getBusinessType, "outbound_type")
                .eq(PrintConfig::getDocumentType, dict.getValue())
                .last("limit 1"));
        WmsDocumentTypeStatus typeStatus = documentTypeStatusService.getOne(new LambdaQueryWrapper<WmsDocumentTypeStatus>()
                .eq(WmsDocumentTypeStatus::getPrintConfigId, config.getId())
                .like(WmsDocumentTypeStatus::getName, "提交")
                .orderByAsc(WmsDocumentTypeStatus::getSort)
                .last("limit 1"));
        base.setCode(typeStatus.getCode());
        WmsOutReceiptPage page = new WmsOutReceiptPage();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//        List<DictModel> dictModels = iSysBaseAPI.queryAllDepartBackDictModel();
//        String deptId = iSysBaseAPI.getDepartIdsByOrgCode(sysUser.getOrgCode());
//        DictModel model = dictModels.stream().filter(a -> deptId.equals(a.getValue())).collect(Collectors.toList()).get(0);
        page.setOrganization(sysUser.getOrgCode());
        page.setDocumentType(dict.getValue());
        page.setDocumentCode(FillRuleUtil.executeRule(FillRuleConstant.OUT_RECEIPT, new JSONObject()).toString());
        page.setOwnerType(plan.getOwnerType());
        page.setOwner(plan.getOwner());
        page.setOutDate(new Date());
        page.setSysOrgCode(sysUser.getOrgCode());
        page.setWmsBasicWarehouseGroupId(plan.getWmsBasicWarehouseGroupId());
        page.setCustomer(plan.getCustomerId());
        page.setDocumentStatus("200");
        List<TakeStockPlanDifferenceMaterial> materialList = takeStockPlanDifferenceMaterialMapper.selectBatchIds(Arrays.asList(byId.getTakeStockPlanDifferenceMaterialId().split(",")));
        List<WmsOutReceiptMaterial> materials = new ArrayList<>();
        for (int i = 0; i < materialList.size(); i++) {
            TakeStockPlanDifferenceMaterial material = materialList.get(i);
            WmsOutReceiptMaterial receiptMaterial = BeanUtil.toBean(material, WmsOutReceiptMaterial.class);
            receiptMaterial.setWmsBasicMaterialId(material.getMaterialId());
            receiptMaterial.setPayableQuantity(new BigDecimal(material.getInventoryLoss()));
            receiptMaterial.setOutboundQuantity(new BigDecimal(material.getInventoryLoss()));
            receiptMaterial.setUpstreamDocuments("盘亏单");
            receiptMaterial.setUpstreamNumber(byId.getCode());
            if (StringUtils.isNotBlank(material.getInventoryLossAssistant())) {
                receiptMaterial.setAssistQuantity(new BigDecimal(material.getInventoryLossAssistant()));
            }
            receiptMaterial.setCreateBy(null);
            receiptMaterial.setCreateTime(null);
            receiptMaterial.setUpdateBy(null);
            receiptMaterial.setUpdateTime(null);
            receiptMaterial.setId(null);
            receiptMaterial.setUpstreamLineNumber(String.valueOf(i + 1));
            receiptMaterial.setProductNumber(material.getProductCode());
            materials.add(receiptMaterial);
        }
        page.setWmsOutReceiptMaterialList(materials);
        base.setData(page);
        workFlowService.commit(base);

        byId.setWmsOutReceiptId(base.getInfoId());
        byId.setGenerateFlag("1");
        this.updateById(byId);
    }
}
